/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = msmq_comm.c                                                   */
/*  NOTE      = MSMQ协议解析                                                  */
/*  DATE      = 2015/08/13 by wuwk                                            */
/******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>

#if defined(FRLINUX4) || defined(FRLINUX5)
    #include "endian_dbg.h"
#else
    #include <endian.h>
#endif

#include "msmq_comm.h"

#define MSMQ_LEN_BASE                        128

union int32_float_bits {
    int32_t int_bits;
    float float_bits;
};

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};


/*******************************************************************************
*  FUNC     :  判断消息优先级
*  ARGS     :  u32_priority (消息优先级)
*  RTN      :  MSMQ_FALSE                  非法
*           :  MSMQ_TRUE                   合法
*  NOTE     :
*******************************************************************************/
int msmq_check_msg_priority(uint32_t u32_priority)
{
    /* 消息优先级为0-7 */
    if (u32_priority > 7)
        return MSMQ_FALSE;

    return MSMQ_TRUE;
}

/*******************************************************************************
*  FUNC     :  取得消息长度
*  ARGS     :  p_st_data (消息长度字符串)
*  RTN      :  uint32_t 消息长度
*  NOTE     :
*******************************************************************************/
uint32_t msmq_get_msglen(Frbyte_Packet *p_st_data)
{
    uint32_t u32_msglen = 0;
    uint32_t *p_s_tmp = NULL;
    char arr_len[5];
    int i_ret = 0;

    if (p_st_data == NULL)
        return 0;

    i_ret = bytebuff_get_bytes(p_st_data, arr_len, 4);
    if (i_ret == FR_FAIL)
        return 0;

    arr_len[4] = '\0';

    p_s_tmp = (uint32_t *)arr_len;
    u32_msglen = le32toh(*p_s_tmp);

    return u32_msglen;
}

/*******************************************************************************
*  FUNC     :  取得char类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_char(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, char *p_report_pre)
{
    uint8_t u8_char = 0;
    char arr_value[2];
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_char);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    snprintf(arr_value, sizeof(arr_value), "%c", u8_char);

    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, arr_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得short类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_short(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, char *p_report_pre)
{
    uint16_t u16_len = 0;
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_LITTLE_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, u16_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得int类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_int(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, char *p_report_pre)
{
    uint32_t u32_len = 0;
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_LITTLE_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, u32_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得long类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_long(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, char *p_report_pre)
{
    uint64_t u64_len = 0;
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_LITTLE_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    i_ret = frreport_body_l7_add_long(p_st_body_data, arr_key, u64_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得float类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_float(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, char *p_report_pre)
{
    uint32_t u32_len = 0;
    float f_value = 0.0;
    char arr_key[64];
    union int32_float_bits u_32bits;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_LITTLE_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    u_32bits.int_bits = u32_len;
    f_value = u_32bits.float_bits;

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    i_ret = frreport_body_l7_add_float(p_st_body_data, arr_key, f_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得double类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_double(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, char *p_report_pre)
{
    uint64_t u64_len = 0;
    double db_value = 0.0;
    char arr_key[64];
    union int64_double_bits u_64bits;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_LITTLE_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    u_64bits.int_bits = u64_len;
    db_value = u_64bits.double_bits;

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    i_ret = frreport_body_l7_add_double(p_st_body_data, arr_key, db_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得boolean类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_boolean(Frreport_body_data *p_st_body_data, Frbyte_Packet *p_st_data, char *p_report_pre)
{
    uint8_t u8_len = 0;
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_char(p_st_data, &u8_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (u8_len != 0)
        u8_len = 1;

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, u8_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得double类型消息
*  ARGS     :  p_st_body_data (上报链表)
            :  p_st_data(消息数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int msmq_get_string(Frreport_body_data *p_st_body_data
                  , Frbyte_Packet *p_st_data
                  , uint32_t u32_data_len
                  , char *p_report_pre)
{
    uint32_t u32_tmp = 0;
    char *p_value = NULL;
    char arr_key[64];
    int i_pow = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    u32_tmp = u32_data_len;
    /* 取长度的位数 */
    while (u32_tmp)
    {
        i_pow++;
        u32_tmp = u32_tmp/MSMQ_LEN_BASE;
    }

    p_value = (char *)frmalloc(u32_data_len - i_pow + 1);
    if (p_value == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, i_pow);
    i_ret = bytebuff_get_bytes(p_st_data, p_value, u32_data_len - i_pow);
    if (i_ret  == FR_FAIL)
    {
        frfree(p_value);
        return FR_FAIL;
    }

    p_value[u32_data_len - i_pow] = '\0';

    snprintf(arr_key, sizeof(arr_key), "%s%smessage.text.1", p_report_pre, MSMQ_REPORT_KEY);

    i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, arr_key, p_value);
    frfree(p_value);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}
